package com.ctrip.cap.ui;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.remote.DesiredCapabilities;

import com.ctrip.cap.common.exception.CapException;
import com.ctrip.cap.exception.AppiumParameterException;

/**
 * Context parameter to appium Capability
 * https://github.com/appium/appium/blob/master
 * /docs/en/writing-running-appium/caps.md
 *
 * @author sqou
 */
public class UIConfig { 

    private String automationName = "UI Automation";
    protected DriverType driverType = DriverType.FirefoxDriver;
	protected String platformName="win7";
	protected String url;
	private Integer newCommandTimeout;
    private static final Set<String> transientKeys = new TreeSet<String>(
	            Arrays.asList("transientKeys", "class", "appFileName", "driverType", "caseLevelRestart"));

	
    public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}
    
	public DriverType getDriverType() {
		return driverType;
	}

	public void setDriverType(DriverType driverType) {
		this.driverType = driverType;
	}
	
    
  
    /**
     * 转化suiteparameter 必要校验
     *
     * @param context
     */
    public UIConfig(Map<String, String> context) {
        BeanMap beanMap = new BeanMap(this);
        for (String k : context.keySet()) {
            String v = context.get(k);
            if (StringUtils.isNotBlank(v)) {
                beanMap.put(k, v);
            }
        }
    }

    public void validate() {
        if (StringUtils.isBlank(platformName)) {
            throw new AppiumParameterException(String.format(
                    "platformName Cann't be Null,may be %s,%s",
                    "win7", "winxp"));
        }

        switch (platformName.toLowerCase()) {
            case "win7":
                if (StringUtils.isNotBlank(driverType.toString())) {
                    this.driverType = DriverType.FirefoxDriver;
                }
                break;
            case "winxp":
                if (StringUtils.isNotBlank(driverType.toString())) {
                    this.driverType = DriverType.FirefoxDriver;
                } 
                break;
            default:
                break;
        }

        if (this.driverType ==DriverType.ChromeDriver || this.driverType == DriverType.IEDriver|| this.driverType==DriverType.FirefoxDriver ) {
            if (StringUtils.isBlank(url)) {
                throw new AppiumParameterException("url can't be null");
            }

        }

    }

    public Capabilities toCapabilities() {
        DesiredCapabilities capabilities = new DesiredCapabilities();
        BeanMap beanMap = new BeanMap(this);
        for (Object key : beanMap.keySet()) {
            if (transientKeys.contains(key)) {
                continue;
            }
            if (beanMap.get(key) == null) {
                continue;
            }
            String key2 = key.toString();
            capabilities.setCapability(key2, beanMap.get(key));
        }
        return capabilities;
    }

    public String getAutomationName() {
        return automationName;
    }

    public void setAutomationName(String automationName) {
        this.automationName = automationName;
    }
    
    public Integer getNewCommandTimeout() {
        return newCommandTimeout;
    }

    public void setNewCommandTimeout(Integer newCommandTimeout) {
        this.newCommandTimeout = newCommandTimeout;
    }
    public UIConfig clone() {
        UIConfig config = new UIConfig(new HashMap<String, String>());
        try {
            BeanUtils.copyProperties(config, this);
        } catch (Exception e) {
            throw new CapException("Appium config copy ", e);
        }
        return config;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this,
                ToStringStyle.MULTI_LINE_STYLE);
    }

    public enum DriverType {
        /**
         * Win7
         */
        Window7,
        /**
         *WIndowxp
         */
        Windowxp,
        /**
         * android browser,chrome,chromebeta
         */
        ChromeDriver,
        /**
         * IE Browser Driver
         */
        IEDriver,
        /*
         * Firefox Driver
         */
        FirefoxDriver,
       
        /**
         * extension need to Modify code XX
         */
        Benchmark;
        public boolean isChromeDriver() {
            return Arrays.asList(Window7, ChromeDriver)
                    .contains(this);
        }
        
        public boolean isIEDriver() {
            return Arrays.asList(Window7, IEDriver)
                    .contains(this);
        }
        
        public boolean isFirefoxDriver() {
            return Arrays.asList(Window7, FirefoxDriver)
                    .contains(this);
        }

    }

}
